package com.boredom.Guts;

import java.util.Date;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.IOException;

/**
 * Class for handling metadata.
 *
 * Metadata is the first section of files in the system, whether saved on disk
 * or sent over the network. The network is able to be oblivious to the content
 * of a message, but must use this class to parse the metadata.
 */
public class MetaData {

	/**
	 * Source of this file is a Group? (false indicates source is a User)
	 */
	private boolean group;

	/**
	 * Source of this file, a name. May be a Group or a User, see group.
	 */
	private String source;


	/**
	 * Time this file was created or modified.
	 *
	 * Files may be copied around, so cannot trust Unix file modification
	 * time.
	 */
	private Date modified;

	/**
	 * A large-scale group
	 */
	private String interestGroup;

	/**
	 * The type of the data the metadata is referencing, usually a class
	 * name.
	 */
	private String type;

	/**
	 * path to be appended part given by FileIO, for location of file
	 */
	private String path;

	/**
	 * Get the <code>Group</code> value.
	 *
	 * @return a <code>boolean</code> value
	 */
	public final boolean getGroup() {
		return group;
	}

	/**
	 * Set the <code>Group</code> value.
	 *
	 * @param newGroup The new Group value.
	 */
	public final void setGroup(final boolean newGroup) {
		this.group = newGroup;
	}

	/**
	 * Get the <code>Source</code> value.
	 *
	 * @return a <code>String</code> value
	 */
	public final String getSource() {
		return source;
	}

	/**
	 * Set the <code>Source</code> value.
	 *
	 * @param newSource The new Source value.
	 */
	public final void setSource(final String newSource) {
		this.source = newSource;
	}

	/**
	 * Get the <code>Modified</code> value.
	 *
	 * @return a <code>Date</code> value
	 */
	public final Date getModified() {
		return modified;
	}

	/**
	 * Set the <code>Modified</code> value.
	 *
	 * @param newModified The new Modified value.
	 */
	public final void setModified(final Date newModified) {
		this.modified = newModified;
	}

	/**
	 * Get the <code>InterestGroup</code> value.
	 *
	 * @return a <code>String</code> value
	 */
	public final String getInterestGroup() {
		return interestGroup;
	}

	/**
	 * Set the <code>InterestGroup</code> value.
	 *
	 * @param newInterestGroup The new InterestGroup value.
	 */
	public final void setInterestGroup(final String newInterestGroup) {
		this.interestGroup = newInterestGroup;
	}

	/**
	 * Get the <code>Type</code> value.
	 *
	 * @return a <code>String</code> value
	 */
	public final String getType() {
		return type;
	}

	/**
	 * Set the <code>Type</code> value.
	 *
	 * @param newType The new Type value.
	 */
	public final void setType(final String newType) {
		this.type = newType;
	}

	/**
	 * Get the <code>Path</code> value.
	 *
	 * @return a <code>String</code> value
	 */
	public final String getPath() {
		return path;
	}

	/**
	 * Set the <code>Path</code> value.
	 *
	 * @param newPath The new Path value.
	 */
	public final void setPath(final String newPath) {
		this.path = newPath;
	}

	/**
	 * Consume and parse metadata from a stream.
	 *
	 * Leaves stream position at start of content, and fills out fields of
	 * this instance. Is called by constructor if possible, may also be
	 * called directly with a different stream.
	 *
	 * @param is The stream, which should be positioned where the metadata
	 *  begins (normally the begining of the file)
	 */
	public void parse (InputStream is) throws IOException {
		BufferedReader reader
			= new BufferedReader (new InputStreamReader (is));
		String line;

		interestGroup = reader.readLine();

		line = reader.readLine ();
		if (line.equals ("1")) {
			group = true;
		} else if (line.equals ("0")) {
			group = false;
		}

		source = reader.readLine ();

		modified = new Date (Long.parseLong (reader.readLine ()));

		type = reader.readLine ();

		path = reader.readLine ();
	}

	/**
	 * Return String representation of the metadata. Used by write() method
	 *
	 * @return String representation of metadata. Can be parsed by parse()
	 *  method
	 */
	public String toString () {
		StringBuilder s =  new StringBuilder (256);

		s.append (interestGroup);
		s.append ("\n");

		if (group) {
			s.append ("1");
		} else {
			s.append ("0");
		}
		s.append ("\n");

		s.append (source);
		s.append ("\n");

		s.append (modified.getTime());
		s.append ("\n");

		s.append (type);
		s.append ("\n");

		s.append (path);
		s.append ("\n");

		return s.toString();
	}

	/**
	 * Write metadata to stream.
	 *
	 * Stream position should be set to location where metadata should be
	 * entered (usually beginning)
	 *
	 * @param os Stream to write metadata to.
	 */
	public void write (OutputStream os) throws IOException {
		BufferedWriter writer
			= new BufferedWriter (new OutputStreamWriter (os));
		writer.write (toString());
	}

	/**
	 * 
	 */
	public String makePathname () {
		return 

	/**
	 * Create an empty container for metadata
	 *
	 * The data should be set and then the instance written out to the file.
	 */
	public MetaData () throws IOException {
	}

	/**
	 * Retrieve metadata from a stream.
	 *
	 * @param is stream to load into metadata. Position is advanced to
	 *  beginning of content.
	 */
	public MetaData (InputStream is) throws IOException {
		parse (is);
	}
}
